Unity Profiler
1. 개요
1. 개요
유니티 프로파일러는 유니티 (게임 엔진)을 사용하여 개발된 애플리케이션의 성능을 분석하고 최적화하는 데 사용되는 내장 도구이다. 유니티 테크놀로지스가 개발한 이 도구는 게임 엔진 에디터에 통합되어 있어, 개발자가 CPU 사용량, GPU 사용량, 메모리 사용량, 렌더링 성능, 오디오 성능, 물리 연산 등 다양한 성능 지표를 실시간으로 모니터링할 수 있게 해준다.
이 도구의 주요 용도는 애플리케이션 실행 중 발생하는 성능 병목 현상을 찾아내고 최적화하는 것이다. 개발자는 프로파일러를 통해 프레임 시간, 배치 호출 수, 트라이앵글 수, 가비지 컬렉션 빈도 등 구체적인 데이터를 확인할 수 있으며, 이를 바탕으로 코드나 에셋, 설정을 조정하여 전반적인 성능을 향상시킬 수 있다.
유니티 프로파일러는 게임 개발과 소프트웨어 최적화 분야에서 필수적인 프로파일링 도구로 자리 잡았다. 에디터 내에서 직접 프로파일링하거나, 스마트폰, 콘솔 게임기 등 실제 타겟 디바이스에 연결하여 프로파일링하는 방식을 지원하며, 고급 분석을 위한 딥 프로파일링 기능과 프레임 디버거와의 연동 기능도 제공한다.
2. 주요 기능
2. 주요 기능
2.1. CPU 사용량 분석
2.1. CPU 사용량 분석
CPU 사용량 분석은 Unity Profiler의 핵심 기능 중 하나로, 애플리케이션 실행 중 CPU가 각 작업에 소비하는 시간을 측정하고 시각화한다. 이를 통해 게임의 프레임 레이트 저하나 끊김 현상의 주요 원인이 되는 CPU 측 성능 병목 현상을 정확히 찾아낼 수 있다. 프로파일러는 CPU 시간을 스크립트, 렌더링, 물리 연산, 가비지 컬렉션 등 세부 카테고리로 분류하여 보여주며, 각 프레임별로 시간 분포를 그래프와 계층적 목록 형태로 제공한다.
분석 창에서는 주로 Hierarchy 뷰와 Timeline 뷰를 사용한다. Hierarchy 뷰는 해당 프레임의 모든 CPU 활동을 총 소요 시간 순으로 나열하며, 각 항목을 클릭하면 호출 스택을 드릴다운하여 특정 함수나 메서드가 소모한 정확한 시간을 확인할 수 있다. Timeline 뷰는 시간 흐름에 따른 CPU 사용량의 변화를 색상으로 구분된 영역 그래프로 보여주어, 문제가 발생한 정확한 프레임을 빠르게 식별하는 데 유용하다.
CPU 프로파일링을 통해 발견할 수 있는 일반적인 문제점으로는 비효율적인 스크립트 로직, 과도한 Update 루프 호출, 빈번한 가비지 컬렉션 발생, 예상치 못한 동기화 대기 시간 등이 있다. 예를 들어, 특정 MonoBehaviour 스크립트의 Update 함수에서 과도한 연산을 수행하거나, 매 프레임 불필요한 컴포넌트 검색을 반복하는 경우 CPU 사용량이 급증하는 것을 확인할 수 있다.
이러한 분석 결과를 바탕으로 개발자는 문제의 근본 원인을 해결할 수 있다. 비용이 큰 함수를 최적화하거나, 코루틴을 활용하여 작업 부하를 분산시키고, 객체 풀링을 도입하여 가비지 컬렉션 발생 빈도를 줄이는 등의 성능 최적화 작업을 수행하게 된다. CPU 사용량 분석은 에디터 내에서뿐만 아니라, 빌드된 애플리케이션을 대상 디바이스에서 원격으로 프로파일링하여 실제 플랫폼의 성능을 정확히 파악하는 데도 필수적이다.
2.2. GPU 사용량 분석
2.2. GPU 사용량 분석
GPU 사용량 분석은 Unity Profiler의 핵심 기능 중 하나로, 애플리케이션의 그래픽 처리 장치 부하를 세부적으로 측정하고 시각화한다. 이 기능은 주로 렌더링 파이프라인에서 발생하는 병목 현상을 식별하는 데 사용되며, 그래픽스 API 호출, 셰이더 연산, 텍스처 업로드, 버퍼 전송 등 GPU 관련 작업의 성능을 분석한다. 프로파일러는 각 렌더링 이벤트(예: 카메라 렌더, 그림자 맵 생성, 포스트 프로세싱 효과)에 소요된 시간을 계층적으로 보여주어, 어떤 단계에서 가장 많은 시간이 소비되는지 명확히 파악할 수 있게 한다.
GPU 프로파일링은 에디터 내에서 또는 빌드된 애플리케이션을 대상으로 실시간 데이터를 수집할 수 있다. 프로파일러 창의 GPU 사용량 그래프와 상세 타이밍 뷰를 통해 개발자는 프레임 내 개별 드로우 콜의 비용, 배칭 효율성, 버텍스 및 픽셀 셰이더의 복잡도 등을 확인할 수 있다. 특히 스크립터블 렌더 파이프라인을 사용하는 프로젝트에서는 각 렌더 패스의 성능 영향을 정밀하게 비교 분석하는 데 유용하다.
이 분석을 통해 발견할 수 있는 일반적인 문제점으로는 과도한 드로우 콜, 비효율적인 셰이더 복잡도, 대용량 텍스처의 불필요한 스트리밍, 프레임 버퍼 오버헤드 등이 있다. 또한 VR이나 고해상도 모바일 게임과 같이 GPU 성능이 중요한 플랫폼에서는 해상도 스케일링, 레벨 오브 디테일, 오클루전 컬링 등의 최적화 기법 적용 효과를 정량적으로 평가하는 기준으로 활용된다.
2.3. 메모리 사용량 분석
2.3. 메모리 사용량 분석
메모리 사용량 분석은 Unity Profiler의 핵심 기능 중 하나로, 애플리케이션이 런타임에 사용하는 메모리 자원을 상세하게 모니터링하고 분석하는 역할을 한다. 이 기능은 메모리 누수를 탐지하거나, 불필요하게 높은 메모리 점유율의 원인을 찾아 최적화하는 데 필수적이다. 프로파일러는 메모리 할당과 해제를 추적하여 힙 메모리의 변화를 실시간 그래프로 보여주며, 특정 프레임에서의 메모리 스냅샷을 찍어 상세 내역을 조사할 수 있다.
분석은 주로 'Memory' 모듈에서 이루어지며, 여기서는 관리되는 힙, 네이티브 힙, 에셋, 게임 오브젝트, 텍스처, 메시 등 다양한 카테고리별로 메모리 사용량을 확인할 수 있다. 특히 가비지 컬렉션이 자주 발생하거나 힙 메모리가 지속적으로 증가하는 경우, 이 영역을 분석하여 어떤 스크립트나 에셋이 원인인지 파악할 수 있다. 프로파일러는 각 할당이 발생한 호출 스택을 제공하여 문제의 정확한 위치를 찾는 데 도움을 준다.
에디터에서 실행 중인 프로젝트뿐만 아니라, 안드로이드나 iOS와 같은 실제 모바일 디바이스에 빌드된 애플리케이션에 연결하여 프로파일링할 수도 있다. 이는 타겟 플랫폼에서의 실제 메모리 사용 패턴을 정확히 파악하는 데 중요하다. 또한 프로파일러 API를 이용해 사용자 정의 메모리 할당에 마커를 추가하거나, 특정 시점의 메모리 상태를 기록하는 등 고급 분석을 수행할 수 있다.
2.4. 렌더링 성능 분석
2.4. 렌더링 성능 분석
렌더링 성능 분석은 Unity Profiler의 핵심 기능 중 하나로, 게임의 시각적 품질을 유지하면서도 원활한 프레임률을 달성하는 데 필수적이다. 이 기능은 그래픽스 파이프라인의 각 단계에서 소요되는 시간과 자원을 세부적으로 보여주어, 렌더링 관련 병목 현상을 정확히 찾아낼 수 있게 한다.
주요 분석 항목으로는 드로우 콜, 배칭, 쉐이더, 텍스처, 라이팅 등이 있다. 프로파일러는 CPU가 렌더 스레드에서 드로우 콜을 준비하는 데 걸리는 시간과, GPU가 실제 폴리곤을 그리는 데 소요되는 시간을 분리하여 표시한다. 이를 통해 병목이 CPU 바운드인지 GPU 바운드인지 명확히 구분할 수 있으며, 배치 호출 수나 트라이앵글 수와 같은 구체적인 렌더링 통계도 확인 가능하다.
렌더링 성능 분석은 특히 프레임 디버거와의 연동을 통해 더욱 강력해진다. 프로파일러에서 문제가 의심되는 프레임을 캡처한 후, 프레임 디버거를 통해 해당 프레임의 모든 렌더링 명령을 단계별로 재현하고 분석할 수 있다. 이를 통해 특정 머티리얼이나 쉐이더가 예상보다 높은 비용을 발생시키는지, 불필요한 오버드로우가 발생하는지 등을 시각적으로 파악하고 최적화할 수 있다.
이러한 분석을 바탕으로 개발자는 LOD (Level of Detail), 오클루전 컬링, 텍스처 압축, 라이트맵 사용 등의 최적화 기법을 효과적으로 적용하여, 최종적으로 애플리케이션의 프레임률과 반응성을 크게 향상시킬 수 있다.
2.5. 오디오 성능 분석
2.5. 오디오 성능 분석
오디오 성능 분석 기능은 Unity (게임 엔진) 애플리케이션에서 오디오 시스템이 차지하는 CPU 및 메모리 사용량을 모니터링하고 병목 현상을 식별하는 데 사용된다. 이 기능은 오디오 소스, 오디오 리스너, 오디오 믹서, 오디오 효과 등 오디오 파이프라인의 각 요소별 자원 소비를 세부적으로 보여준다. 특히 동시에 재생되는 오디오 클립의 수, 디코딩 부하, 믹싱 오버헤드, 3D 사운드 공간화 처리 비용 등을 분석할 수 있어, 복잡한 사운드 환경에서의 성능 문제를 진단하는 데 필수적이다.
주요 분석 지표로는 오디오 업데이트에 소요되는 CPU 시간, 활성화된 오디오 채널 수, 스트리밍 오디오의 디스크 읽기 부하, 오디오 필터나 리버브 존 적용에 따른 추가 연산 비용 등이 있다. 프로파일러는 이러한 데이터를 시각화하여 특정 오디오 클립이나 이벤트가 과도한 자원을 사용하는 지점을 쉽게 찾을 수 있도록 돕는다. 이를 통해 개발자는 불필요한 오디오 소스를 비활성화하거나, 오디오 풀링을 구현하고, 압축 포맷을 최적화하는 등 효율적인 오디오 관리를 수행할 수 있다.
2.6. 물리 연산 분석
2.6. 물리 연산 분석
물리 연산 분석 기능은 유니티 (게임 엔진) 애플리케이션에서 물리 엔진의 성능 영향을 측정하고 최적화하는 데 중점을 둔다. 이 기능은 주로 CPU 사용량 프로파일링의 일부로 제공되며, 게임 오브젝트 간의 충돌 감지, 강체 시뮬레이션, 조인트 계산 등 유니티 내장 물리 시스템(PhysX) 또는 다른 물리 엔진이 소비하는 시간을 세부적으로 보여준다. 프로파일러 창에서는 물리 업데이트, 충돌 검사, 물리 쿼리 등 각 물리 작업이 한 프레임에서 차지하는 밀리초 단위 시간을 확인할 수 있어, 복잡한 물리 시뮬레이션이 프레임 속도에 미치는 영향을 정량적으로 분석할 수 있다.
프로파일러는 물리 성능 병목 현상을 구체적으로 파악하는 데 도움을 준다. 예를 들어, 과도한 수의 콜라이더를 가진 오브젝트, 복잡한 메시 콜라이더 사용, 불필요하게 높은 업데이트 주기의 리지드바디, 또는 비효율적으로 구성된 물리 레이어 간 상호작용 등이 주요 원인으로 지목될 수 있다. 또한, 물리 시뮬레이션 단계와 고정 업데이트 주기와의 관계도 분석 대상이 된다. 고정 업데이트 빈도가 너무 높으면 물리 계산 부하가 증가하고, 반대로 너무 낮으면 물리 시뮬레이션의 정확도가 떨어질 수 있기 때문이다.
이러한 분석을 바탕으로 개발자는 여러 최적화 기법을 적용할 수 있다. 정적 배경 오브젝트에는 리지드바디 컴포넌트를 추가하지 않거나, 단순한 프리미티브 콜라이더(박스, 구, 캡슐)를 복잡한 메시 콜라이더 대신 사용하는 것이 일반적이다. 또한, 물리적으로 상호작용하지 않는 오브젝트들은 서로 다른 물리 레이어에 배치하여 불필요한 충돌 검사 계산을 줄일 수 있다. 프로파일러의 물리 연산 분석은 이러한 변경 사항이 실제 성능에 얼마나 기여하는지를 즉시 피드백해 주므로, 체계적인 물리 시스템 튜닝을 가능하게 한다.
3. 프로파일링 방법
3. 프로파일링 방법
3.1. 에디터 내 프로파일링
3.1. 에디터 내 프로파일링
에디터 내 프로파일링은 Unity (게임 엔진) 에디터에서 게임을 실행하면서 실시간으로 성능 데이터를 수집하고 분석하는 가장 기본적이고 일반적인 방법이다. 개발자는 Unity Profiler 창을 열고 에디터의 플레이 모드를 시작하기만 하면, 게임 뷰와 함께 프로파일러 창에서 프레임 시간, CPU 사용량, 메모리 할당 등 다양한 성능 지표가 실시간으로 시각화되어 표시되는 것을 확인할 수 있다.
이 방식의 주요 장점은 빠른 반복 작업이 가능하다는 점이다. 코드를 수정하거나 에셋을 조정한 후 즉시 플레이 모드를 다시 실행하여 변경 사항이 성능에 미치는 영향을 확인할 수 있다. 프로파일러는 각 프레임을 세부적인 타임라인으로 보여주며, 스크립트 실행, 렌더링, 물리 연산 등 각 카테고리가 전체 프레임 시간에서 차지하는 비중을 한눈에 파악할 수 있게 한다.
에디터 내 프로파일링은 주로 초기 개발 단계와 빠른 프로토타이핑에 유용하다. 그러나 에디터 자체의 오버헤드가 포함되고, 최종 빌드된 애플리케이션의 성능과는 차이가 있을 수 있다는 한계가 있다. 따라서 정확한 목표 플랫폼의 성능을 측정하기 위해서는 디바이스 프로파일링이 필수적으로 따라와야 한다.
3.2. 디바이스 프로파일링
3.2. 디바이스 프로파일링
디바이스 프로파일링은 Unity (게임 엔진) 에디터 외부에서 실행되는 실제 빌드된 애플리케이션의 성능을 분석하는 방법이다. Unity Profiler는 Wi-Fi 네트워크나 USB 케이블을 통해 스마트폰, 태블릿, 게임 콘솔 등 대상 디바이스에 연결하여 실시간 성능 데이터를 수집하고 에디터의 프로파일러 창에서 확인할 수 있게 한다. 이 방식은 에디터 환경과 실제 하드웨어에서의 성능 차이를 명확히 파악하는 데 필수적이다.
디바이스 프로파일링을 수행하려면, 먼저 Unity 프로젝트를 대상 플랫폼으로 빌드하고, 빌드 시 스크립트 디버깅 옵션을 활성화해야 한다. 그 후 Unity 에디터에서 프로파일러 창을 열고, 연결 대상으로 '플레이어'를 선택하여 디바이스와 연결을 설정한다. 성공적으로 연결되면 디바이스에서 애플리케이션이 실행되는 동안 CPU 사용량, 메모리 할당, 렌더링 통계 등 모든 프로파일링 데이터가 에디터로 실시간 스트리밍되어 표시된다.
이 방법의 주요 장점은 개발 중인 PC의 성능에 의존하지 않고, 최종 사용자가 경험할 실제 성능을 정확히 측정할 수 있다는 점이다. 특히 모바일 장치의 경우 제한된 프로세서 성능, 배터리, 발열 영향 등을 고려한 최적화가 중요하므로, 디바이스 프로파일링은 필수적인 작업 과정으로 여겨진다. 또한 AR이나 VR 애플리케이션처럼 특정 하드웨어와 밀접한 연관이 있는 프로젝트의 성능 분석에도 유용하게 활용된다.
3.3. 딥 프로파일링
3.3. 딥 프로파일링
딥 프로파일링은 Unity Profiler의 고급 프로파일링 모드로, 스크립트 코드의 모든 함수 호출을 세밀하게 추적하고 측정하는 기능이다. 일반 프로파일링 모드보다 더 상세한 정보를 제공하지만, 성능 오버헤드가 크게 증가한다는 특징이 있다. 이 모드는 주로 특정 코드 블록이나 함수의 정확한 실행 시간을 분석하여 성능 병목 현상을 정밀하게 찾아내는 데 사용된다.
딥 프로파일링을 활성화하면 Unity (게임 엔진) 엔진은 모든 스크립트 함수의 진입과 종료를 모니터링하며, 각 함수가 소비한 CPU 시간을 기록한다. 이를 통해 게임 오브젝트의 Update 루틴이나 특정 알고리즘 내에서 어떤 함수가 가장 많은 시간을 차지하는지 명확하게 확인할 수 있다. 이 모드는 에디터 내에서 실행 중인 게임이나 빌드된 애플리케이션에 연결하여 사용할 수 있다.
이 기능은 성능 오버헤드가 매우 크기 때문에, 전체 게임 플레이를 분석하는 데 사용하기보다는 의심되는 특정 구간이나 프레임에만 제한적으로 적용하는 것이 일반적이다. 프로파일러 창에서 'Deep Profile' 버튼을 눌러 활성화할 수 있으며, 활성화된 동안에는 애플리케이션의 실행 속도가 현저히 저하될 수 있다.
딥 프로파일링으로 얻은 데이터는 CPU 사용량 분석 창에서 계층적 트리 뷰로 확인할 수 있다. 여기서는 함수의 총 소요 시간, 자체 소요 시간, 호출 횟수 등을 확인하여 최적화가 필요한 핵심 함수를 식별할 수 있다. 이 정보는 반복문 최적화, 불필요한 함수 호출 제거, 알고리즘 개선 등 스크립트 성능 병목 현상을 해결하는 데 결정적인 근거를 제공한다.
3.4. 프레임 디버거 연동
3.4. 프레임 디버거 연동
Unity Profiler는 Unity (게임 엔진)의 프레임 디버거와 긴밀하게 연동되어 작동한다. 이 연동 기능은 주로 렌더링 성능 분석과 최적화 과정에서 중요한 역할을 한다. 프로파일러에서 특정 프레임의 성능 문제를 감지하면, 사용자는 해당 프레임을 프레임 디버거로 직접 전송하여 더욱 세부적인 렌더링 정보를 확인할 수 있다.
프레임 디버거로 전송된 프레임에서는 드로우 콜의 정확한 순서와 내용, 사용된 셰이더, 텍스처, 머티리얼 정보를 단계별로 검토할 수 있다. 이를 통해 특정 배치 호출이 비효율적인 이유나 불필요한 렌더링 패스가 발생하는 지점을 시각적으로 파악하는 것이 가능해진다. 이는 복잡한 그래픽스 문제의 근본 원인을 찾는 데 매우 효과적인 방법이다.
이러한 통합 워크플로우는 성능 병목 현상의 원인이 CPU에 있는지, GPU에 있는지, 아니면 렌더링 파이프라인 자체에 있는지를 명확히 구분하는 데 도움을 준다. 프로파일러의 수치 데이터와 프레임 디버거의 시각적 데이터를 함께 분석함으로써 개발자는 보다 정확하고 효율적인 성능 최적화 결정을 내릴 수 있다.
4. 성능 최적화 지표
4. 성능 최적화 지표
4.1. 프레임 시간
4.1. 프레임 시간
프레임 시간은 Unity Profiler에서 가장 핵심적인 성능 지표 중 하나이다. 이는 게임이 하나의 완전한 화면을 생성하고 표시하는 데 걸리는 총 시간을 의미하며, 일반적으로 밀리초(ms) 단위로 측정된다. 낮은 프레임 시간은 높은 프레임 레이트와 부드러운 게임 플레이를 보장한다. 프로파일러는 이 시간을 프레임별로 상세히 기록하여, 특정 프레임에서 성능이 저하되는 시점과 그 원인을 정확히 파악할 수 있게 해준다.
프레임 시간은 주로 CPU 처리 시간과 GPU 렌더링 시간으로 구성된다. 프로파일러의 CPU 사용량 분석 창에서는 각 프레임을 렌더링하는 동안 실행된 모든 스크립트 함수, 물리 연산, 애니메이션 업데이트, 렌더링 명령 발행 등이 소요한 시간을 계층적으로 보여준다. 이를 통해 특정 스크립트 로직이나 시스템 호출이 프레임 시간을 증가시키는 주요 원인인지 식별할 수 있다.
반면, GPU 사용량 분석은 그래픽스 파이프라인에서 버텍스 셰이딩, 픽셀 셰이딩, 렌더 타겟 전환 등 각 단계가 소비한 시간을 표시한다. 복잡한 셰이더, 과도한 드로우 콜, 높은 해상도의 텍스처 등이 GPU 측면의 프레임 시간을 늘리는 일반적인 요인이다. CPU와 GPU 시간을 종합적으로 분석하여 병목 현상이 어디에 있는지 판단하는 것이 성능 최적화의 첫걸음이다.
프레임 시간 분석의 목표는 이를 일정한 목표치 이하로 유지하는 것이다. 예를 들어, 60FPS를 목표로 한다면 프레임 시간은 약 16.67ms를 넘지 않아야 한다. 프로파일러는 이러한 목표 시간을 초과하는 프레임을 쉽게 찾아내고, 해당 프레임에서 발생한 모든 이벤트의 상세 타이밍을 제공하여 개발자가 성능 병목 현상을 정밀하게 해결할 수 있도록 지원한다.
4.2. 배치 호출 수
4.2. 배치 호출 수
배치 호출 수는 Unity (게임 엔진)의 렌더링 성능을 평가하는 핵심 지표 중 하나이다. 이는 CPU가 GPU에게 한 프레임 내에 전달하는 렌더링 명령의 횟수를 의미한다. 각 배치 호출은 드로우 콜이라고도 불리며, 그래픽스 API를 통해 특정 머티리얼과 메시를 사용하여 오브젝트를 그리라는 명령에 해당한다. 배치 호출 자체에는 오버헤드가 존재하기 때문에, 호출 횟수가 많을수록 CPU가 렌더링 준비에 소비하는 시간이 증가하여 전체 프레임 시간에 부정적인 영향을 미칠 수 있다.
배치 호출 수를 줄이는 것은 렌더링 성능 최적화의 주요 목표이다. 이를 위해 Unity (게임 엔진)은 정적 배칭과 동적 배칭 같은 자동화된 배칭 기술을 제공한다. 정적 배칭은 움직이지 않는(Transform 컴포넌트가 고정된) 오브젝트들을 런타임 이전에 하나의 큰 메시로 결합하여 단일 배치 호출로 렌더링한다. 동적 배칭은 특정 조건(동일한 머티리얼 사용, 작은 크기의 메시 등)을 만족하는 움직이는 오브젝트들을 런타임에 자동으로 배칭한다.
Unity Profiler의 렌더링 영역에서는 배치 호출 수를 실시간으로 모니터링할 수 있다. 프로파일러는 배치 호출의 총 수와 함께, 정적 배칭과 동적 배칭에 의해 얼마나 많은 호출이 절약되었는지를 보여주는 통계도 제공한다. 배치 호출 수가 예상보다 높게 나타난다면, 이는 머티리얼 인스턴스가 과도하게 많거나, 배칭 조건을 충족하지 못하는 오브젝트들이 많다는 신호일 수 있다. GPU 인스턴싱을 활용하거나, 아틀라스 텍스처를 통해 머티리얼을 공유하는 방식으로 배치 호출을 더욱 효과적으로 줄일 수 있다.
4.3. 트라이앵글 수
4.3. 트라이앵글 수
트라이앵글 수는 Unity Profiler의 렌더링 성능 분석에서 핵심적으로 추적하는 지표 중 하나이다. 이는 GPU가 1프레임 동안 처리해야 하는 삼각형(폴리곤)의 총 개수를 의미하며, 렌더링 부하와 직접적인 연관이 있다. 일반적으로 트라이앵글 수가 많을수록 GPU의 정점 처리(Vertex Processing) 작업량이 증가하여 프레임 시간이 길어지고 성능 저하를 초래할 수 있다.
이 지표는 주로 프로파일러의 렌더링 영역에서 확인할 수 있으며, 장면(Scene)의 시각적 복잡도를 수치화하는 중요한 척도로 사용된다. 개발자는 이 수치를 모니터링하여 특정 카메라 뷰에서 불필요하게 많은 트라이앵글을 그리는 오브젝트를 식별하고, LOD(Level of Detail) 시스템 적용이나 메시 최적화를 통해 수를 줄이는 최적화 작업을 수행할 수 있다.
트라이앵글 수는 배치 호출 수(Draw Call)와 함께 분석하는 것이 효과적이다. 배치 호출이 적더라도 한 번의 호출에 너무 많은 트라이앵글을 그리면 GPU 병목 현상이 발생할 수 있으며, 반대로 트라이앵글 수는 적지만 배치 호출이 과도하게 많으면 CPU 병목 현상이 발생할 수 있다. 따라서 양쪽 지표를 균형 있게 관리하는 것이 렌더링 파이프라인 최적화의 핵심이다.
최적화 대상 | 주로 영향을 받는 하드웨어 | 관련 프로파일러 지표 |
|---|---|---|
과도한 트라이앵글 수 | GPU (정점 처리) | 렌더링 영역의 Triangles |
과도한 배치 호출 수 | CPU (렌더링 명령 준비) | 렌더링 영역의 Batches |
성능 목표에 따라 허용 가능한 트라이앵글 수는 타겟 플랫폼의 성능에 따라 크게 달라진다. 고사양 PC 또는 최신 게임 콘솔에서는 수백만 개까지도 처리 가능할 수 있지만, 모바일 장치나 VR 애플리케이션에서는 훨씬 낮은 수준으로 제한하는 것이 일반적이다.
4.4. 가비지 컬렉션
4.4. 가비지 컬렉션
가비지 컬렉션은 Unity Profiler의 '메모리 사용량 분석' 영역에서 모니터링할 수 있는 핵심 성능 지표 중 하나이다. 이는 C# 프로그래밍 언어와 .NET 기반의 Mono 또는 IL2CPP 스크립팅 백엔드 환경에서 동작하는 Unity (게임 엔진) 애플리케이션의 메모리 관리 시스템을 가리킨다. 개발자가 생성한 객체 중 더 이상 참조되지 않는 객체를 자동으로 탐지하고 해제하여 메모리를 회수하는 과정이다.
프로파일러의 가비지 컬렉션 뷰에서는 가비지 컬렉션이 발생한 정확한 프레임과 해당 수집 작업에 소요된 시간(밀리초 단위)을 확인할 수 있다. 갑작스러운 프레임 드랍의 주요 원인으로 작용할 수 있기 때문에, 이 수치가 높거나 빈번하게 나타난다면 성능 병목 현상이 발생하고 있음을 의미한다. 프로파일러는 각 프레임별 힙 메모리 할당량과 함께 가비지 컬렉션 활동을 시각적으로 표시하여 문제를 진단하는 데 도움을 준다.
성능 최적화를 위해서는 가비지 컬렉션의 발생 빈도와 소요 시간을 최소화하는 것이 중요하다. 이를 위해 개발자는 매 프레임마다 불필요한 새로운 객체의 할당을 줄이는 코딩 패턴을 적용해야 한다. 예를 들어, 반복적으로 사용되는 객체는 오브젝트 풀링 기법을 통해 재사용하고, 문자열 연산 시에는 StringBuilder를 활용하는 등의 방법이 있다.
가비지 컬렉션으로 인한 지연을 상세히 분석하려면 프로파일러의 딥 프로파일링 모드를 활성화하는 것이 유용하다. 이 모드는 모든 함수 호출을 추적하여, 어떤 스크립트 코드가 과도한 힙 메모리 할당을 유발하고 있는지 구체적으로 찾아낼 수 있게 해준다. 이를 통해 코드 수준에서 정확한 최적화 지점을 파악하고, 게임의 전반적인 실행 흐름을 원활하게 유지할 수 있다.
5. 고급 기능
5. 고급 기능
5.1. 프로파일러 모듈 확장
5.1. 프로파일러 모듈 확장
Unity Profiler는 기본적으로 제공되는 모듈 외에도 추가적인 모듈을 확장하여 프로파일링 범위를 넓힐 수 있다. 이러한 확장성은 개발자가 특정 시스템이나 커스텀 코드의 성능을 분석해야 할 때 유용하다. Unity는 프로파일러 API를 통해 이러한 모듈 확장 기능을 공식적으로 지원한다.
확장 모듈은 주로 Unity 패키지 매니저를 통해 설치하거나, 직접 C# 스크립트로 개발하여 통합할 수 있다. 예를 들어, 특정 네트워크 라이브러리의 성능을 측정하거나, 데이터베이스 쿼리 시간을 분석하는 모듈을 추가할 수 있다. 이를 통해 프로파일러 창에서 기존의 CPU 사용량이나 메모리 사용량 그래프와 함께 새로운 데이터 계층을 시각적으로 확인할 수 있다.
확장 모듈을 개발하기 위해서는 Unity 엔진이 제공하는 ProfilerMarker API나 IProfilerWindowController 인터페이스 등을 활용한다. 이러한 API를 사용하면 애플리케이션 실행 중 특정 코드 블록의 실행 시간을 측정하고, 그 결과를 프로파일러의 타임라인 뷰에 커스텀 카테고리로 표시할 수 있다. 이는 게임플레이 로직이나 에셋 로딩 파이프라인 등 엔진 기본 모듈이 커버하지 않는 영역의 성능 병목을 찾는 데 필수적이다.
결과적으로, 프로파일러 모듈 확장 기능은 Unity 개발 환경을 매우 유연하게 만들어, 다양한 서드파티 애셋이나 복잡한 게임 시스템 전반에 걸친 정밀한 성능 프로파일링을 가능하게 한다. 이는 최종 애플리케이션의 성능과 안정성을 높이는 데 기여한다.
5.2. 사용자 정의 프로파일러 마커
5.2. 사용자 정의 프로파일러 마커
사용자 정의 프로파일러 마커는 개발자가 Unity Profiler의 표준 프로파일링 범주 외에 자신만의 코드 구간을 명시적으로 표시하고 측정할 수 있게 해주는 기능이다. 이를 통해 게임 로직, 특정 알고리즘, 외부 시스템 호출 등 애플리케이션의 임의 영역에 대한 상세한 성능 데이터를 수집할 수 있다. 주로 C 샤프 스크립트 내에서 Profiler.BeginSample()과 Profiler.EndSample() 메서드 쌍을 사용하거나, Unity 2020.3 이후 버전에서는 ProfilerMarker API를 활용하여 더 효율적으로 구현한다.
이 기능을 사용하면 프로파일러 창의 CPU 사용량 그래프 내에 사용자가 지정한 이름의 마커가 생성되어, 해당 코드 블록이 실행되는 데 소요된 정확한 시간과 호출 빈도를 시각적으로 확인할 수 있다. 이는 복잡한 게임 시스템에서 성능 병목 현상이 정확히 어디에서 발생하는지, 예를 들어 특정 AI 행동 트리 평가나 복잡한 데이터 구조 처리 과정에서 시간이 많이 소요되는지를 파악하는 데 필수적이다.
사용자 정의 마커는 특히 멀티스레딩 작업이나 코루틴과 같은 비동기 작업의 성능을 분석할 때 유용하다. 또한, 프로파일링 데이터는 빌드된 실행 파일에서도 수집할 수 있어, 실제 디바이스에서의 성능을 정확히 진단하는 데 기여한다. 이를 통해 개발자는 추측이 아닌 데이터에 기반한 성능 최적화를 수행할 수 있다.
5.3. 프로파일러 API
5.3. 프로파일러 API
Unity Profiler는 성능 데이터를 수집하고 표시하는 기능 외에도, 개발자가 코드 내에서 직접 프로파일링 정보를 생성하고 제어할 수 있는 API를 제공한다. 이 API는 주로 UnityEngine.Profiling 네임스페이스 아래에 위치하며, C# 스크립트를 통해 접근할 수 있다. 이를 통해 개발자는 특정 코드 블록의 실행 시간을 측정하거나, 사용자 정의 성능 마커를 프로파일러 타임라인에 추가하여 애플리케이션의 성능 동작을 더 세밀하게 분석할 수 있다.
가장 일반적으로 사용되는 API 중 하나는 Profiler.BeginSample과 Profiler.EndSample 메서드 쌍이다. 이 메서드들을 사용하면 특정 함수나 코드 구간의 CPU 사용 시간을 프로파일러에 명시적으로 기록할 수 있다. 예를 들어, 복잡한 알고리즘이나 자주 호출되는 함수의 성능을 정확히 측정할 때 유용하다. 또한 ProfilerMarker 구조체를 사용하면 보다 효율적이고 안전한 방식으로 동일한 작업을 수행할 수 있으며, 특히 자주 실행되는 코드 경로에서 성능 오버헤드를 최소화하는 데 도움이 된다.
프로파일러 API는 성능 데이터 수집 자체를 제어하는 기능도 포함한다. Profiler.enabled 프로퍼티를 통해 런타임 중에 프로파일링을 동적으로 활성화하거나 비활성화할 수 있으며, Profiler.logFile을 설정하여 프로파일링 데이터를 파일로 저장할 수 있다. 이는 빌드된 애플리케이션에서 특정 상황이나 플레이어의 동작 이후에 성능 데이터를 수집해야 하는 경우에 활용된다. 수집된 .raw 파일은 다시 Unity 에디터의 프로파일러 창에서 불러와 분석할 수 있다.
이러한 API를 효과적으로 사용하면, 프로파일러가 자동으로 수집하는 광범위한 시스템 데이터 사이에서 개발자가 관심 있는 사용자 코드의 성능 정보를 부각시킬 수 있다. 이는 복잡한 게임이나 애플리케이션에서 성능 병목 현상의 정확한 위치를 빠르게 찾고, 최적화 작업의 효과를 정량적으로 평가하는 데 필수적인 도구가 된다.
6. 주요 문제 해결
6. 주요 문제 해결
6.1. 프레임 드랍 원인 분석
6.1. 프레임 드랍 원인 분석
프레임 드랍은 게임이나 애플리케이션의 실행이 순간적으로 끊기는 현상으로, Unity Profiler를 사용하면 그 원인을 체계적으로 분석할 수 있다. 주요 원인은 크게 CPU 병목, GPU 병목, 메모리 문제로 나눌 수 있으며, 프로파일러의 각 모듈을 통해 구체적인 원인을 파악한다.
CPU 병목 현상은 가장 흔한 프레임 드랍의 원인이다. 스크립트의 비효율적인 로직, 과도한 물리 연산, 빈번한 가비지 컬렉션 호출 등이 CPU 시간을 과도하게 소모하여 프레임 생성을 지연시킨다. 프로파일러의 CPU 사용량 분석 창에서는 프레임 내에서 각 함수가 소요한 시간을 계층적으로 확인할 수 있어, 처리 시간이 가장 긴 함수를 쉽게 찾아낼 수 있다. 특히 '딥 프로파일링' 모드를 활성화하면 모든 함수 호출을 세부적으로 추적하여 병목 구간을 정확히 특정할 수 있다.
GPU 병목 현상은 주로 복잡한 셰이더, 과도한 드로우 콜, 높은 해상도의 텍스처, 많은 트라이앵글 수에서 발생한다. 프로파일러의 GPU 사용량 분석 모듈을 사용하면 각 렌더링 패스에 소요된 시간을 확인할 수 있다. 렌더링 성능 분석 모듈과 연동하여 배치 호출 수나 셰이더의 연산 복잡도 등을 함께 분석하면, 그래픽스 파이프라인에서의 병목 지점을 명확히 찾아낼 수 있다.
메모리 관련 문제도 프레임 드랍을 유발한다. 갑작스러운 대량의 메모리 할당은 가비지 컬렉션을 유발하여 CPU에 부하를 준다. 프로파일러의 메모리 영역에서는 할당된 힙 메모리의 크기와 변화 추이, 특정 프레임에서 발생한 메모리 할당량을 실시간으로 모니터링할 수 있다. 이를 통해 불필요한 객체 생성이나 해제되지 않는 메모리 누수의 징후를 발견하여, 프레임 드랍과 연관된 메모리 관리 문제를 해결할 수 있다.
6.2. 메모리 누수 탐지
6.2. 메모리 누수 탐지
Unity Profiler는 게임 개발 과정에서 발생할 수 있는 메모리 누수를 탐지하고 분석하는 데 필수적인 도구이다. 메모리 누수는 애플리케이션이 더 이상 필요하지 않은 객체를 계속 참조하여 가비지 컬렉터가 회수하지 못하게 하고, 결국 사용 가능한 메모리를 고갈시키는 문제를 일으킨다.
메모리 누수 탐지를 위해 프로파일러의 메모리 섹션을 주로 활용한다. 여기서는 힙 메모리 할당 추이, 특정 게임 오브젝트나 애셋의 참조 횟수, 가비지 컬렉션이 발생하는 빈도와 소요 시간 등을 실시간으로 확인할 수 있다. 특히 시간 경과에 따른 힙 메모리 사용량 그래프가 꾸준히 상승하는 패턴을 보인다면 메모리 누수가 발생하고 있을 가능성이 높다.
정확한 누수 원인을 찾기 위해서는 딥 프로파일링 모드를 활성화한 상태에서 장시간 프로파일링을 수행하거나, 특정 시나리오(예: 특정 씬을 반복 로드)를 재현하며 메모리 할당을 추적한다. 프로파일러는 각 프레임별로 할당된 객체의 유형과 크기, 할당을 발생시킨 호출 스택을 제공하여, 어떤 스크립트 코드가 예상치 못한 메모리 할당을 반복하는지 식별하는 데 도움을 준다.
또한, 프로파일러 API를 통해 코드에 사용자 정의 프로파일러 마커를 추가하면, 특정 함수나 로직 블록의 메모리 영향도를 세밀하게 측정할 수 있다. 이를 통해 정적 변수나 이벤트 리스너, 캐시 등에 잘못 남아 있는 참조로 인한 누수를 효과적으로 찾아낼 수 있다.
6.3. 배치 호출 최적화
6.3. 배치 호출 최적화
배치 호출 최적화는 Unity (게임 엔진)에서 렌더링 성능을 향상시키기 위한 핵심 기법이다. 배치 호출이란 CPU가 GPU에게 한 번의 명령으로 여러 오브젝트를 그리도록 요청하는 것을 의미하며, 이 횟수를 줄이는 것이 중요하다. 배치 호출 수가 많을수록 CPU의 렌더링 관련 부하가 증가하여 프레임 드랍을 유발할 수 있다. Unity Profiler의 렌더링 창이나 프레임 디버거를 통해 현재 씬의 배치 호출 수와 그 원인을 정확히 파악할 수 있다.
배치 호출을 최적화하는 주요 방법은 정적 배칭과 동적 배칭, 그리고 GPU 인스턴싱을 활용하는 것이다. 정적 배칭은 움직이지 않는 오브젝트들을 사전에 하나의 큰 메시로 결합하여 드로우 콜을 줄인다. 동적 배칭은 런타임에 조건을 만족하는 이동하는 오브젝트들을 자동으로 배치한다. GPU 인스턴싱은 동일한 메시와 머티리얼을 사용하는 오브젝트들을 매우 효율적으로 한 번에 렌더링하는 고급 기법이다.
최적화 기법 | 적용 대상 | 주요 조건 |
|---|---|---|
정적 배칭 | 움직이지 않는 오브젝트 | 오브젝트에 |
동적 배칭 | 이동하는 오브젝트 | 정점 수 제한, 동일한 머티리얼 사용, 트랜스폼에 음수 스케일 없음 |
GPU 인스턴싱 | 동일 메시/머티리얼 오브젝트 | 셰이더가 인스턴싱 지원, SRP 배처 사용 가능 |
머티리얼을 공유하는 오브젝트의 수를 늘리고, 불필요하게 다른 머티리얼을 사용하는 경우를 줄이는 것이 기본 원칙이다. 또한 아틀라스 기법을 통해 여러 텍스처를 하나의 큰 텍스처로 합치고, 이를 참조하는 머티리얼을 하나로 통일하면 배칭 효율을 극대화할 수 있다. LOD (컴퓨터 그래픽스) 시스템을 적용하여 카메라에서 멀리 떨어진 오브젝트의 렌더링 부하를 줄이는 것도 간접적으로 배치 호출 관리에 도움이 된다.
6.4. 스크립트 성능 병목 현상
6.4. 스크립트 성능 병목 현상
스크립트 성능 병목 현상은 Unity Profiler를 사용하여 분석하고 해결할 수 있는 주요 문제 중 하나이다. 이는 게임 로직을 담당하는 C# 스크립트의 비효율적인 코드 실행으로 인해 전체 프레임 레이트가 저하되는 현상을 의미한다. 프로파일러의 CPU 사용량 분석 창을 통해 각 스크립트 함수, 특히 Update 메서드나 물리 계산을 담당하는 FixedUpdate 메서드의 실행 시간을 정밀하게 측정할 수 있다. 이를 통해 특정 함수가 예상보다 많은 프레임 시간을 소모하는 지점, 즉 병목 현상을 빠르게 식별할 수 있다.
병목 현상의 일반적인 원인으로는 과도한 가비지 컬렉션 발생, 비효율적인 알고리즘 사용, 불필요하게 빈번한 컴포넌트 접근, 그리고 과도한 반복문 사용 등이 있다. 프로파일러는 이러한 원인을 구체적으로 보여주며, 예를 들어 가비지 컬렉션으로 인한 주기적인 프레임 끊김은 메모리 할당 그래프를 통해 확인할 수 있다. 스크립트 최적화를 위해서는 객체 풀링을 도입하여 메모리 할당을 줄이거나, 비용이 큰 연산 결과를 캐시에 저장하여 재사용하며, 코루틴을 적절히 활용하여 부하를 분산시키는 방법 등이 있다.
프로파일러의 딥 프로파일링 모드를 활성화하면 모든 함수 호출을 세부적으로 추적할 수 있어, 병목 현상의 정확한 위치를 코드 라인 수준까지 파악하는 데 도움이 된다. 또한, 사용자 정의 프로파일러 마커를 활용하면 개발자가 직접 특정 코드 블록의 성능을 프로파일링 대상으로 지정하여 분석의 정밀도를 높일 수 있다. 이러한 도구들을 체계적으로 사용함으로써 스크립트 성능 병목 현상을 효과적으로 해결하고, 전반적인 애플리케이션의 반응성과 사용자 경험을 크게 향상시킬 수 있다.
